using System;
using System.Diagnostics;
using FluentParser.Expressions;

namespace FluentParser.Expressions.Rules.Decoration
{
    /// <summary>
    /// Decorates a symbol by transforming it into a symbol.
    /// This allows to remove it's resulting value.
    /// </summary>
    /// <typeparam name="TSource">Type of the source expression</typeparam>
    /// <example><code>
    /// var parseExpression = ...;
    /// Symbol parseSymbol = parseExpression.ToSymbol();
    /// </code></example>
    [DebuggerDisplay("[CastToSymbolRule Source={Source.GetType().Name}]")]
    public class CastToSymbolRule<TSource> : Symbol
    {
        public BaseExpr<TSource> Source { get; private set; }

        public CastToSymbolRule(BaseExpr<TSource> source)
        {
            Source = source;
            TypeOperation = OperationType.Conversion;
        }

        public override ParsingResult<object> Parse(GrammarContext context, int index)
        {
            ParsingResult<TSource> result = Source.Parse(context, index);
            if (result == null)
                return null;

            return new ParsingResult<object>(result.Index, result.Length, result);
        }

        public override void ParseNode(GrammarContext context, ParsingNodeResult node)
        {
            ParsingNodeResult childNode = node.AddChild(Source, context);

            if (childNode.IsSuccess)
            {
                node.Value = String.Concat(childNode.Value);
                node.IsSuccess = true;
            }
        }
    }
}